<template>
    <div>
        <m-filter>
            <a-button type="primary" @click="openModal(undefined, 0)">
                <a-icon type="plus"></a-icon>
                新增菜单
            </a-button>
        </m-filter>
        <div class="table">
            <a-table
                :rowKey="record => 'id_' + record.id"
                :columns="columns"
                class="no-pagination-table"
                :data-source="tableData"
                :loading="tableLoading"
                :pagination="false"
                :customRow="customRow"
                :scroll="{ y: true }"
                :key="tableKey"
                defaultExpandAllRows
            >
                <template slot="operate" slot-scope="text, record">
                    <span class="primary-color" @click="openModal(record, 1)" v-if="!record.router.includes(':')">
                        添加下级菜单
                    </span>
                    <a-divider type="vertical" v-if="!record.router.includes(':')" />
                    <span class="primary-color" @click="openModal(record, 2)">编辑</span>
                    <a-divider type="vertical" v-if="!record.children || !record.children.length" />
                    <a-popconfirm title="确定删除吗?" ok-text="是" cancel-text="否" @confirm="del(record.id)">
                        <span class="danger-color" v-if="!record.children || !record.children.length">删除</span>
                    </a-popconfirm>
                </template>
            </a-table>
        </div>
        <modal
            v-if="isShowModal"
            :currRow="currRow"
            :isShowModal.sync="isShowModal"
            :modalType="modalType"
            :menuOptions="[...tableData]"
            @getTableData="getTableData"
        />
    </div>
</template>

<script>
import modal from './modal'
import { sortMinToNull, getTreeData } from '@/utils/methods'
import { menusApi } from '../../../common/api/setting'
import MFilter from '../../../components/filter'

export default {
    name: 'menus',
    components: {
        modal,
        MFilter,
    },
    data() {
        return {
            // modal
            isShowModal: false,
            modalType: -1,
            // table
            currRow: undefined,
            tableData: [],
            tableKey: 0,
            columns: [
                {
                    title: '菜单名称',
                    dataIndex: 'label',
                    align: 'left',
                },
                {
                    title: '菜单路由',
                    dataIndex: 'router',
                    align: 'left',
                },
                {
                    title: '操作',
                    dataIndex: 'operate',
                    align: 'left',
                    scopedSlots: { customRender: 'operate' },
                },
            ],
            tableLoading: false,
        }
    },
    watch: {},
    mounted() {
        this.getTableData()
    },
    methods: {
        openModal(record, modalType) {
            this.modalType = modalType
            this.currRow = record
            this.isShowModal = true
        },
        del(delId) {
            menusApi.del({ id: delId }).then(() => {
                this.$message.success('删除成功')
                this.getTableData()
            })
        },
        customRow(record) {
            return {
                attrs: {
                    draggable: true, // 设置拖拽属性
                },
                style: {
                    cursor: 'pointer',
                },
                on: {
                    // 开始拖拽
                    dragstart: event => {
                        const ev = event || window.event
                        ev.stopPropagation()
                        // 得到源数据
                        this.sourceRow = record
                        console.log(this.sourceRow, 'this.sourceObj')
                    },
                    // 拖动元素经过的元素
                    dragover: event => {
                        const ev = event || window.event
                        ev.preventDefault()
                        // 还原之前经过节点的样式
                        this.dragoverNode && (this.dragoverNode.className = '')
                        // 只能同级移动
                        if (this.sourceRow.permissionPid !== record.permissionPid) {
                            return
                        }
                        // 给当前经过节点设置样式
                        this.dragoverNode = document.querySelector(`tr[data-row-key=id_${record.id}]`)
                        if (record.index > this.sourceRow.index) {
                            this.dragoverNode.className = 'drop-over-downward'
                        }
                        if (record.index < this.sourceRow.index) {
                            this.dragoverNode.className = 'drop-over-upward'
                        }
                    },
                    // 鼠标松开
                    drop: event => {
                        const ev = event || window.event
                        ev.stopPropagation()
                        this.dragoverNode && (this.dragoverNode.className = '')
                        if (this.sourceRow.id === record.id) {
                            return
                        }
                        // 只能同级移动
                        if (this.sourceRow.permissionPid !== record.permissionPid) {
                            return
                        }
                        // 得到目标数据
                        this.targetRow = record
                        console.log(this.targetRow, 'this.targetObj')
                        this.moveRow()
                    },
                },
            }
        },
        moveRow() {
            let changeData
            const exchange = list => {
                let isFind = false
                const targetRow = this.targetRow
                const sourceRow = this.sourceRow
                for (let index = list.length - 1; index >= 0; index--) {
                    const { id, children } = list[index]
                    if (!isFind) {
                        if (id === targetRow.id || id === sourceRow.id) {
                            isFind = true
                            // 找到排序前的空sort的开始位置
                            const sortBeforeNullSortStartIndex = list.findIndex(
                                ({ sort }) => sort === undefined || sort === null || sort === '',
                            )
                            const sourceIndex = list.findIndex(item => item.id === sourceRow.id)
                            const targetIndex = list.findIndex(item => item.id === targetRow.id)
                            console.log('sourceIndex:', sourceIndex, sourceRow.id)
                            console.log('targetIndex:', targetIndex, targetRow.id)
                            // 交换元素位置
                            // list.splice(targetIndex, 1, ...list.splice(sourceIndex, 1, list[targetIndex]));

                            // 替换元素位置 其他元素相应移动
                            const tmp = list[sourceIndex]
                            // 删除源
                            list.splice(sourceIndex, 1)
                            // 将源插入到目标位置
                            list.splice(targetIndex, 0, tmp)
                            // 找到更新的数据
                            let laragerIndex = -1
                            let smallerIndex = -1
                            if (this.targetRow.index > this.sourceRow.index) {
                                laragerIndex = this.targetRow.index
                                smallerIndex = this.sourceRow.index
                            } else {
                                laragerIndex = this.sourceRow.index
                                smallerIndex = this.targetRow.index
                            }
                            if (sortBeforeNullSortStartIndex > -1 && sortBeforeNullSortStartIndex < smallerIndex) {
                                smallerIndex = sortBeforeNullSortStartIndex
                            }
                            changeData = list.slice(smallerIndex, laragerIndex + 1)
                            console.log(smallerIndex, 'smallerIndex')
                            // 设置sort
                            if (smallerIndex !== 0) {
                                console.log(list[smallerIndex - 1].sort, 'list[smallerIndex - 1].sort')
                                changeData.forEach((item, index) => {
                                    item.sort = list[smallerIndex - 1].sort + (index + 1)
                                })
                            } else {
                                changeData.forEach((item, index) => {
                                    item.sort = index
                                })
                            }
                            // 重新设置index
                            list.forEach((item, index) => {
                                item.index = index
                            })
                        } else {
                            if (children?.length) {
                                exchange(children)
                            }
                        }
                    }
                }
            }
            const tableData = _.cloneDeep(this.tableData)
            exchange(tableData)
            // 执行更新
            const hide = this.$message.loading('正在更新...', 0)
            console.log(changeData, 'changeData')
            menusApi
                .sortMenu(changeData.map(({ sort, id }) => ({ sort, id })))
                .then(() => {
                    this.tableData = [...tableData]
                    this.$message.success('更新成功', 2.5)
                })
                .finally(() => {
                    hide()
                })
        },
        formatTable(tableData) {
            const customSomeKey = list => {
                list = sortMinToNull(list)
                console.log(list, 'list')
                list.forEach((item, index) => {
                    item.index = index
                    if (item.children?.length) {
                        customSomeKey(item.children)
                    }
                })
            }
            customSomeKey(tableData)
            return tableData
        },
        onSearch() {
            this.getTableData()
        },
        getTableData() {
            this.tableLoading = true
            menusApi.get().then(res => {
                if (res.code == 200) {
                    this.tableData = this.formatTable(getTreeData(res.data, 'id', 'permissionPid'))
                    this.tableKey++
                    this.tableLoading = false
                }
            })
        },
    },
}
</script>

<style lang="scss" scoped>
/deep/.drop-over-downward td {
    border-bottom: 2px dashed #1890ff !important;
}

/deep/.drop-over-upward td {
    border-top: 2px dashed #1890ff !important;
}
</style>
